/**
 * <p>Title: MaterialBatchSvcImpl</p>
 * <p>Description: The Implements of MaterialBatchSvc</p>
 * <p>Copyright: Shanghai Batchsight Pharmaceutical Technologies, Inc. Copyright(c) 2016</p>
 * @author Wan Shuaishuai
 * @version 1.0
 * <pre>Histroy:
 *       2016-11-23  Wan Shuaishuai  Create
 *</pre>
*/
package cn.jhg.account.service;

import java.sql.Timestamp;

import java.util.List;
import javax.annotation.Resource;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import cn.jhg.account.persist.MaterialBatchPropertyDao;
import cn.jhg.account.entity.AuditTrailObject;
import cn.jhg.account.entity.AuditTrailRecord;
import cn.jhg.account.entity.AuditTrailType;
import cn.jhg.account.entity.MaterialBatch;
import cn.jhg.account.persist.MaterialBatchDao;
import cn.jhg.account.service.AuditTrailSvc;
import cn.jhg.account.util.SequenceProducer;
import cn.jhg.account.util.ServiceResult;
@Transactional
@Service("materialBatchSvc")
public class MaterialBatchSvcImpl implements MaterialBatchSvc{
	@Resource
	private MaterialBatchDao materialBatchDao;
	@Resource
	private MaterialBatchPropertyDao materialBatchPropertyDao;
	@Resource
	private SequenceProducer sequenceProducer;// 注入模拟序列类
	@Resource
	private AuditTrailSvc auditTrailSvc;
	Logger logger=LoggerFactory.getLogger(MaterialBatchSvcImpl.class);
	
	/**
	 * <p> Function: addBatch </p>
	 * <p> Description: 新增原料批次</p>
	 * @param batch	批次实体
	 * @param sid	签名id
	 * @param iuid	调用人id
	 * @return	ServiceResult<Integer>  批次id，ErrorCode
	 */
	@Override
	public ServiceResult<Integer> addBatch(MaterialBatch batch, int sid, int iuid) {
		ServiceResult<Integer> result = new ServiceResult<Integer>();
		try{
			String batchNo = batch.getBatchNo();
			MaterialBatch no = materialBatchDao.findByBatchNo(batchNo);
			if(no!=null){
				result.setErrorCode(223090276);//添加原料批次失败，批次号已存在
				logger.error("[ERR223090276] 新增原料批次失败，批次号已存在");
			}else{
				int id = sequenceProducer.nextval("t_ibcp_material_batch");
				ObjectId obId = new ObjectId();
				batch.setPropId(obId.toHexString());
				batch.setId(id);
				materialBatchPropertyDao.addBatchProperty(batch);//往mongodb中添加数据
				materialBatchDao.addBatch(batch);//往mySql中添加数据
				result.setErrorCode(0);
				result.setData(id);
				logger.info("[INF223090278] 新增原料批次成功");
				
				// 添加审计追踪记录
				AuditTrailRecord atRecord = new AuditTrailRecord();
				atRecord.setSid(sid); // 签名 id
				atRecord.setUid(iuid); // 用户 id
				atRecord.setLid(100); //  位置id
				atRecord.setTid(AuditTrailType.AddBatch.GetId()); // 审计追踪类型 id
				atRecord.setOtid(AuditTrailObject.MaterialBatch.getId());    // 审计追踪对象 id

				Document metadata = new Document(); // 审计追踪元数据
				metadata.append("Id", id);//审计追踪记录批次id
				metadata.append("batchNo", batchNo);//审计追踪记录批次号
				atRecord.setMeta(metadata);
				auditTrailSvc.addRecord(atRecord);
			}//else 语句结束
			return result;
		}catch(Exception e){//try 语句结束
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090402);
			logger.error("[ERR223090402] 异常:添加原料批次失败" + e.getMessage());
			return result;
		} 
	}

	/**
	 * <p> Function: updateBatch </p>
	 * <p> Description: 更新原料批次</p>
	 * @param batch	批次实体
	 * @param sid	签名id
	 * @param iuid	调用人id
	 * @return	ServiceResult<Object> ErrorCode
	 */
	@Override
	public ServiceResult<Object> updateBatch(MaterialBatch batch, int sid, int iuid) {
		ServiceResult<Object> result = new ServiceResult<Object>();
		try{
			String batchNo = batch.getBatchNo();
			int id = batch.getId();
			MaterialBatch no = materialBatchDao.findByBatchNo(batchNo);
			if(no!=null&&id!=no.getId()){
				result.setErrorCode(223090422);//更新原料批次失败，批次号已存在
				logger.error("[ERR223090422] 更新原料批次失败，批次号已存在");
			}else{
				materialBatchPropertyDao.updateBatchProperty(batch);//更新mongodb中的数据
				materialBatchDao.updateBatch(batch);//更新mySql中的数据
				result.setErrorCode(0);
				logger.info("[INF223090436] 更新原料批次成功");
				
				// 添加审计追踪记录
				AuditTrailRecord atRecord = new AuditTrailRecord();
				atRecord.setSid(sid); // 签名 id
				atRecord.setUid(iuid); // 用户 id
				atRecord.setLid(100); //  位置id
				atRecord.setTid(AuditTrailType.UpdateBatch.GetId()); // 审计追踪类型 id
				atRecord.setOtid(AuditTrailObject.MaterialBatch.getId());    // 审计追踪对象 id

				Document metadata = new Document(); // 审计追踪元数据
				metadata.append("Id", id);//审计追踪记录批次id
				metadata.append("batchNo", batchNo);//审计追踪记录批次号
				atRecord.setMeta(metadata);
				auditTrailSvc.addRecord(atRecord);
			}//else 语句结束
			return result;
		}catch(Exception e){//try  语句结束
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090447);
			logger.error("[ERR223090447] 异常:更新原料批次失败" + e.getMessage());
			return result;
		} 
	}

	/**
	 * <p> Function: deleteBatch </p>
	 * <p> Description: 删除原料批次</p>
	 * @param id  批次id
	 * @param sid	签名id
	 * @param iuid	调用人id
	 * @return	ServiceResult<Object> ErrorCode
	 */
	@Override
	public ServiceResult<Object> deleteBatch(int id, int sid, int iuid) {
		ServiceResult<Object> result = new ServiceResult<Object>();
		try{
			MaterialBatch batch = materialBatchDao.queryBatchById(id);
			materialBatchDao.deleteBatch(id);//删除mySql中的数据
			ObjectId oid = new ObjectId(batch.getPropId());
			materialBatchPropertyDao.deleteBatchProperty(oid);//删除mongodb中的数据
			result.setErrorCode(0);
			logger.info("[INF223090476] 删除原料批次成功");
			
			// 添加审计追踪记录
			AuditTrailRecord atRecord = new AuditTrailRecord();
			atRecord.setSid(sid); // 签名 id
			atRecord.setUid(iuid); // 用户 id
			atRecord.setLid(100); //  位置id
			atRecord.setTid(AuditTrailType.DeleteBatch.GetId()); // 审计追踪类型 id
			atRecord.setOtid(AuditTrailObject.MaterialBatch.getId());    // 审计追踪对象 id

			Document metadata = new Document(); // 审计追踪元数据
			metadata.append("Id", id);//审计追踪记录批次id
			atRecord.setMeta(metadata);
			auditTrailSvc.addRecord(atRecord);
			
			return result;
		}catch(Exception e){//try 语句结束
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090486);
			logger.error("[ERR223090486] 异常:删除原料批次失败" + e.getMessage());
			return result;
		} 
	}

	/**
	 * <p> Function: queryBatchById </p>
	 * <p> Description: 通过批次id查询原料批次</p>
	 * @param id  批次id
	 * @param iuid	调用人id
	 * @return	ServiceResult<MaterialBatch> 批次实体，ErrorCode
	 */
	@Override
	public ServiceResult<MaterialBatch> queryBatchById(int id, int iuid) {
		ServiceResult<MaterialBatch> result = new ServiceResult<MaterialBatch>();
		try{			
			MaterialBatch batch = materialBatchDao.queryBatchById(id);//查询mySql中数据
			ObjectId oid = new ObjectId(batch.getPropId());
			Document property = materialBatchPropertyDao.queryBatchPropertyById(oid);//查询mongodb中数据
			batch.setProperty(property);
			result.setData(batch);
			result.setErrorCode(0);
			logger.info("[INF223090577] 通过批次id查询原料批次成功");
			return result;
		}catch(Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090587);
			logger.error("[ERR223090587] 异常:通过批次id查询原料批次失败" + e.getMessage());
			return result;
		} 
	}

	/**
	 * <p> Function: findBatch </p>
	 * <p> Description: 通过batchNo，manuName，statId查询原料批次</p>
	 * @param batchNo	批次号	
	 * @param manuName	生产厂名称
	 * @param statId	状态代码
	 * @param iuid		调用人id
	 * @return	ServiceResult<List<Integer>> 批次id集合，ErrorCode
	 */
	@Override
	public ServiceResult<List<Integer>> findBatch(String batchNo, String manuName, int statId, int iuid) {
		ServiceResult<List<Integer>> result = new ServiceResult<List<Integer>>();
		try{	
			batchNo = "%"+ batchNo +"%";
			manuName = "%"+ manuName +"%";
			MaterialBatch batch = new MaterialBatch();
			batch.setBatchNo(batchNo);
			batch.setManuName(manuName);
			batch.setStatId(statId);
			List<Integer> list = materialBatchDao.findBatch(batch);
			result.setData(list);
			result.setErrorCode(0);
			logger.info("[INF223090644] 通过batchNo，manuName，statId查询原料批次id成功");
			return result;
		}catch(Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090716);
			logger.error("[ERR223090716] 异常:通过batchNo，manuName，statId查询原料批次id失败" + e.getMessage());
			return result;
		} 
	}

	/**
	 * <p> Function: findBatchDetail </p>
	 * <p> Description: 通过batchNo，manuName，statId查询原料批次</p>
	 * @param batchNo	批次号	
	 * @param manuName	生产厂名称
	 * @param statId	状态代码
	 * @param iuid		调用人id
	 * @return	ServiceResult<List<MaterialBatch>> 批次实体集合，ErrorCode
	 */
	@Override
	public ServiceResult<List<MaterialBatch>> findBatchDetail(String batchNo, String manuName, int statId, int iuid) {
		ServiceResult<List<MaterialBatch>> result = new ServiceResult<List<MaterialBatch>>();
		try{	
			batchNo = "%"+ batchNo +"%";
			manuName = "%"+ manuName +"%";
			MaterialBatch batch = new MaterialBatch();
			batch.setBatchNo(batchNo);
			batch.setManuName(manuName);
			batch.setStatId(statId);
			List<MaterialBatch> list = materialBatchDao.findBatchDetail(batch);
			result.setData(list);
			result.setErrorCode(0);
			logger.info("[INF223090777] 通过batchNo，manuName，statId查询原料批次成功");
			return result;
		}catch(Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090824);
			logger.error("[ERR223090824] 异常:通过batchNo，manuName，statId查询原料批次失败" + e.getMessage());
			return result;
		}
	}

	/**
	 * <p> Function: checkExpiredDate </p>
	 * <p> Description: 检查批次有效期</p>
	 * @param timestamp	时间戳
	 * @param iuid		调用人id
	 * @return	ServiceResult<Set<Integer>> 有效期超过 timestamp 所指定时间的批次id集合 ，ErrorCode
	 */
	@Override
	public ServiceResult<List<Integer>> checkExpiredDate(Timestamp timestamp, int iuid) {
		ServiceResult<List<Integer>> result = new ServiceResult<List<Integer>>();
		try{	
			List<Integer> batch = materialBatchDao.checkExpiredDate(timestamp);
			if(batch==null){
				result.setErrorCode(223090834);//检查批次有效期失败
				logger.error("[ERR223090834] 检查批次有效期失败");
			}else{
				result.setData(batch);
				result.setErrorCode(0);
				logger.info("[INF223090847] 检查批次有效期成功");
			}
			return result;
		}catch(Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223090859);
			logger.error("[ERR223090859] 异常:检查批次有效期失败" + e.getMessage());
			return result;
		}
	}

	/**
	 * <p> Function: checkInspectionDate </p>
	 * <p> Description: 检查批次复检期</p>
	 * @param timestamp	时间戳
	 * @param iuid		调用人id
	 * @return ServiceResult<Integer> 复检期超过 timestamp 所指定时间的批次id集合，ErrorCode
	 */
	@Override
	public ServiceResult<List<Integer>> checkInspectionDate(Timestamp timestamp, int iuid) {
		ServiceResult<List<Integer>> result = new ServiceResult<List<Integer>>();
		try{	
			List<Integer> batch = materialBatchDao.checkInspectionDate(timestamp);
			if(batch==null){
				result.setErrorCode(223090868);//检查批次复检期
				logger.error("[ERR223090868] 检查批次复检期失败");
			}else{
				result.setData(batch);
				result.setErrorCode(0);
				logger.info("[INF223090973] 检查批次复检期成功");
			}
			return result;
		}catch(Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			result.setErrorCode(223091006);
			logger.error("[ERR223091006] 异常:检查批次复检期失败" + e.getMessage());
			return result;
		}
	}
	
}
